package org.tigris.atlas.examples.service;

import org.tigris.atlas.messages.Messages;
import org.tigris.atlas.service.ServiceResponse;
import org.tigris.atlas.examples.service.delegate.EntityMaintenanceServiceDelegate;
import org.tigris.atlas.examples.service.delegate.ServiceDelegateFactory;
import org.tigris.atlas.examples.transfer.NoLockTest;
import org.tigris.atlas.examples.transfer.NoLockTestPK;
import org.tigris.atlas.examples.transfer.OplockChild;
import org.tigris.atlas.examples.transfer.OplockParent;
import org.tigris.atlas.examples.transfer.TransferObjectFactory;

import junit.framework.TestCase;

public class TestOplock extends TestCase {
	
	EntityMaintenanceServiceDelegate service;

	protected void setUp() throws Exception {
		super.setUp();
		
		service = ServiceDelegateFactory.createEntityMaintenanceServiceDelegate();
		
	}

	protected void tearDown() throws Exception {
		super.tearDown();
		
		service = null;
	}
	
	public void testOplockCreation() throws Exception {
		OplockParent parent = TransferObjectFactory.createOplockParent();
		parent.setSomeData("testOplockCreation");
		Integer originalOplock = parent.getOplock();
		
		assertNull("Oplock should not be set programmatically!", originalOplock);
		
		OplockParentServiceResponse response = service.save(parent);		
		verfiyErrors(response);
				
		Integer returnedOplock = response.getOplockParent().getOplock();
		assertNotNull("Oplock should have been set!", returnedOplock);
		
	}
	
	
	public void testOplockUpdateWithoutChanges() throws Exception {
		OplockParent parent = TransferObjectFactory.createOplockParent();
		parent.setSomeData("testOplockUpdateWithoutChanges");
		
		OplockParentServiceResponse response = service.save(parent);		
		verfiyErrors(response);
		parent = response.getOplockParent();
		Integer oldOplock = parent.getOplock();
		
		//no changes - should NOT increment oplock:
		OplockParentServiceResponse afterUpdateResponse = service.save(parent);		
		verfiyErrors(afterUpdateResponse);
		Integer newOplock = afterUpdateResponse.getOplockParent().getOplock();
		
		assertEquals("Oplock should NOT have been incremented!", oldOplock.intValue(), newOplock.intValue());
	}
	
	
	public void testOplockParentChildCreation() throws Exception {
		OplockParent parent = TransferObjectFactory.createOplockParent();
		parent.setSomeData("testOplockParentChildCreation - parent");		
		OplockChild child = TransferObjectFactory.createOplockChild();
		child.setSomeMoreData("testOplockParentChildCreation - child");
		parent.addOplockChild(child);
		
		assertNull("Oplock parent should not be set programmatically!", parent.getOplock());
		assertNull("Oplock child should not be set programmatically!", child.getOplock());
		
		OplockParentServiceResponse response = service.save(parent);		
		verfiyErrors(response);
		parent = response.getOplockParent();
		child = (OplockChild)parent.getOplockChilds().iterator().next();
		
		Integer returnedParentOplock = parent.getOplock();
		assertNotNull("Oplock should have been set!", returnedParentOplock);		
		Integer returnedChildOplock = child.getOplock();
		assertNotNull("Oplock should have been set!", returnedChildOplock);
		
	}	
	
	
	public void testOplockDisabling() throws Exception {
		//first, create the initial cut of data:
		NoLockTest originalParent = TransferObjectFactory.createNoLockTest();
		originalParent.setSomeData("original");
		
		NoLockTestServiceResponse response = service.save(originalParent);		
		verfiyErrors(response);
		originalParent = response.getNoLockTest();
		
		//reselect the data so we have duplicate copies:
		NoLockTestPK pk = (NoLockTestPK)originalParent.getKey();
		NoLockTestServiceResponse reselectedResponse = service.findByPrimaryKey(pk);
		NoLockTest reselectedParent = reselectedResponse.getNoLockTest();
		
		//update the second set and save it:
		reselectedParent.setSomeData("updateViaReselectedObject");
		reselectedResponse = service.save(reselectedParent);
		verfiyErrors(reselectedResponse);
		reselectedParent = reselectedResponse.getNoLockTest();
		
		//finally, update orignial object and try to save:
		originalParent.setSomeData("badUpdate");
		NoLockTestServiceResponse shouldNotFailResponse = service.save(originalParent);
		verfiyErrors(shouldNotFailResponse);
	}	
	
	private void verfiyErrors(ServiceResponse parent) {
		assertNotNull("The service response should contain an entity!", parent);
		Messages messages = parent.getMessages();
		int numberOfErrors = (messages != null) ? messages.getErrorMessageCount() : 0;
		assertFalse("No errors should have been returned!", numberOfErrors > 0);
	}	
	
}
